package $2_2coreclasses;

import java.util.Arrays;

public class StringCoding {

    public static void main(String[] args) {
        // String与编码
        // 在Java中，String是一个引用类型，它本身也是一个class。
        // 实际上字符串在String内部是通过一个char[]数组表示的。
        // Java字符串的一个重要特点就是字符串不可变。这种不可变性是通过内部的private final char[]字段，以及没有任何修改char[]的方法实现的。
        
        String s = "Hello";
        System.out.println(s);
        s = s.toUpperCase();
        System.out.println(s);
        s = "Hello";
        // 字符串比较，必须使用equals()方法而不能用==。要忽略大小写比较，使用equalsIgnoreCase()方法。
        // String类还提供了多种方法来搜索子串、提取子串。常用的方法有：
        
        // 是否包含子串:
        "Hello".contains("ll"); // true
        // contains()方法的参数是CharSequence而不是String，因为CharSequence是String的父类
        System.out.println("Hello".indexOf("l")); // 2
        System.out.println("Hello".lastIndexOf("l")); // 3
        System.out.println("Hello".startsWith("He")); // true
        System.out.println("Hello".endsWith("lo")); // true
        // 注意索引号是从0开始的。
        System.out.println("Hello".substring(2)); // "llo"
        System.out.println("Hello".substring(2, 4)); // "ll"
        // 去除首尾空白字符
        // 使用trim()方法可以移除字符串首尾空白字符。空白字符包括空格，\t，\r，\n：
        // 注意：trim()并没有改变字符串的内容，而是返回了一个新字符串。
        System.out.println("  \tHello\r\n ");
        System.out.println("  \tHello\r\n ".trim()); // "Hello"
        
        // 另一个strip()方法也可以移除字符串首尾空白字符。它和trim()不同的是，类似中文的空格字符\u3000也会被移除。
        System.out.println("\u3000Hello\u3000".strip()); // "Hello"
        System.out.println(" Hello ".stripLeading()); // "Hello "
        System.out.println(" Hello ".stripTrailing()); // " Hello"
        // String还提供了isEmpty()和isBlank()来判断字符串是否为空和空白字符串。
        System.out.println("".isEmpty()); // true，因为字符串长度为0
        System.out.println("  ".isEmpty()); // false，因为字符串长度不为0
        System.out.println("  \n".isBlank()); // true，因为只包含空白字符
        System.out.println(" Hello ".isBlank()); // false，因为包含非空白字符
        // 替换子串
        // 要在字符串中替换子串，有两种方法。一种是根据字符或字符串替换：
        System.out.println(s.replace('l', 'w')); // "hewwo"，所有字符'l'被替换为'w'
        System.out.println(s.replace("ll", "~~")); // "he~~o"，所有子串"ll"被替换为"~~"
        // 另一种是通过正则表达式替换：
        System.out.println(s = "A,,B;C ,D");
        System.out.println(s.replaceAll("[\\,\\;\\s]+", ",")); // "A,B,C,D"
        
        // 分割字符串
        // 要分割字符串，使用split()方法，并且传入的也是正则表达式
        s = "A,B,C,D";
        String[] ss = s.split("\\,"); // {"A", "B", "C", "D"}
        System.out.println(Arrays.toString(ss));
        
        // 拼接字符串
        // 拼接字符串使用静态方法join()，它用指定的字符串连接字符串数组
        String[] arr = {"A", "B", "C"};
        String s1 = String.join("***", arr); // "A***B***C"
        System.out.println(s1);
        
        // 格式化字符串
        // 字符串提供了formatted()方法和format()静态方法，可以传入其他参数，替换占位符，然后生成新的字符串
        // 有几个占位符，后面就传入几个参数。参数类型要和占位符一致。我们经常用这个方法来格式化信息。常用的占位符有：
        // %s：显示字符串；
        // %d：显示整数；
        // %x：显示十六进制整数；
        // %f：显示浮点数。
        String s2 = "Hi %s, your score is %d!";
        System.out.println(s2.formatted("Alice", 80));
        System.out.println(String.format("Hi %s, your score is %.2f!", "Bob", 59.5));
        // 类型转换
        // 要把任意基本类型或引用类型转换为字符串，可以使用静态方法valueOf()。这是一个重载方法，编译器会根据参数自动选择合适的方法
        System.out.println(String.valueOf(123)); // "123"
        System.out.println(String.valueOf(45.67)); // "45.67"
        System.out.println(String.valueOf(true)); // "true"
        System.out.println(String.valueOf(new Object())); // 类似java.lang.Object@636be97c
        // 要把字符串转换为其他类型，就需要根据情况。例如，把字符串转换为int类型：
        int n1 = Integer.parseInt("123"); // 123
        int n2 = Integer.parseInt("ff", 16); // 按十六进制转换，255
        System.out.println(n1);
        System.out.println(n2);
        // 把字符串转换为boolean类型：
        boolean b1 = Boolean.parseBoolean("true"); // true
        boolean b2 = Boolean.parseBoolean("FALSE"); // false
        System.out.println(b1);
        System.out.println(b2);
        // 要特别注意，Integer有个getInteger(String)方法，它不是将字符串转换为int，而是把该字符串对应的系统变量转换为Integer
        System.out.println(Integer.getInteger("java.version")); // 版本号，11
        // 转换为char[]
        // String和char[]类型可以互相转换，方法是
        char[] cs = "Hello".toCharArray(); // String -> char[]
        String s3 = new String(cs); // char[] -> String
        System.out.println(cs);
        System.out.println(s3);

        // 小结
        // Java字符串String是不可变对象；
        // 字符串操作不改变原字符串内容，而是返回新字符串；
        // 常用的字符串操作：提取子串、查找、替换、大小写转换等；
        // Java使用Unicode编码表示String和char；
        // 转换编码就是将String和byte[]转换，需要指定编码；
        // 转换为byte[]时，始终优先考虑UTF-8编码。

    }

}
